package org.vison.wonfu.framework.soa.context;

import java.util.Map;
import java.util.Optional;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;

public class ClientContextAttachment extends ContextAttachment {
    // Raw attachment holder
    protected final ConcurrentMap<String, Object> rawAttachments = new ConcurrentHashMap<>();

    public ConcurrentMap<String, Object> getRawAttachments() {
        return rawAttachments;
    }

    public void putRawAttachment(String key, Object value) {
        rawAttachments.put(key, value);
    }

    public void putRawAttachmentIfAbsent(String key, Object value) {
        rawAttachments.putIfAbsent(key, value);
    }

    public void putAllRawAttachments(Map<String, Object> map) {
        if (map == null) {
            return;
        }
        this.rawAttachments.putAll(map);
    }

    Object removeRawAttachment(String key) {
        return rawAttachments.remove(key);
    }

    public Object getRawAttachment(String key) {
        return rawAttachments.get(key);
    }

    public Object getRawAttachment(String key, Object defaultValue) {
        return rawAttachments.getOrDefault(key, defaultValue);
    }

    public String getRawAttachmentString(String key) {
        return Optional.of(rawAttachments)
                .map(a -> a.get(key))
                .filter(v -> v instanceof String)
                .map(Object::toString)
                .orElse(null);
    }

    public String getRawAttachmentString(String key, String defaultValue) {
        return Optional.of(rawAttachments)
                .map(a -> a.get(key))
                .filter(v -> v instanceof String)
                .map(Object::toString)
                .orElse(defaultValue);
    }

    /**
     * deep copy
     **/
    public ClientContextAttachment copy() {
        ClientContextAttachment copy = new ClientContextAttachment();

        if (!this.attachments.isEmpty()) {
            copy.attachments.putAll(this.attachments);
        }
        if (!this.rawAttachments.isEmpty()) {
            copy.rawAttachments.putAll(this.rawAttachments);
        }


        return copy;
    }
}
